package com.example.designpattern.behavioral.interpreter;

import java.util.Stack;

/**
 * 通过一个简单的例子来学习解释器模式：使用中文编写出十以内的加减法公式。比如：
 * <p>
 * 输入“一加一”，输出结果 2
 * 输入“一加一加一”，输出结果 3
 * 输入“二加五减三”，输出结果 4
 * 输入“七减五加四减一”，输出结果 5
 * 输入“九减五加三减一”，输出结果 6
 */
public class Calculator {
    /**
     * 需要注意的是，入栈出栈过程并不会执行真正的计算，栈操作只是将表达式组装成一个嵌套的类对象而已。比如：
     * <p>
     * “一加一”表达式，经过入栈出栈操作后，生成的对象是 new Add(new Number('一'), new Number('一'))
     * “二加五减三”表达式，经过入栈出栈操作后，生成的对象是 new Sub(new Add(new Number('二'), new Number('五')), new Number('三'))
     * 最后一步 stack.pop().interpret()，将栈顶的元素弹出，执行 interpret() ，这时才会执行真正的计算。计算时会将中文的数字和运算符分别解释成计算机能理解的指令。
     *
     * @param expression
     * @return
     */
    public int calculate(String expression) {
        Stack<Expression> stack = new Stack<>();
        for (int i = 0; i < expression.length(); i++) {
            char word = expression.charAt(i);
            switch (word) {
                case '加':
                    stack.push(new Add(stack.pop(), new Number(expression.charAt(++i))));
                    break;
                case '减':
                    stack.push(new Sub(stack.pop(), new Number(expression.charAt(++i))));
                    break;
                default:
                    stack.push(new Number(word));
                    break;
            }
        }
        return stack.pop().interpret();
    }

    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        System.out.println(calculator.calculate("一加一加一"));
    }
}
